package org.apache.skywalking.apm.plugin.kepler.define;

import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.DeclaredInstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;

import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static org.apache.skywalking.apm.agent.core.plugin.match.ClassAnnotationMatch.byClassAnnotationMatch;

/**
 * @author WeiHui-Z
 * @version v1.0.0
 * @date 2019/5/17 20:41
 * @since JDK 1.8
 */
public class KeplerHandlerPluginDefine extends ClassInstanceMethodsEnhancePluginDefine {

	/**
	 * Enhance class.
	 */
	private static final String HANDLER_ANNOTATION = "com.xiaomaoguai.fcp.pre.kepler.router.annotation.HandlerAnnotation";

	/**
	 * Intercept class.
	 */
	private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.kepler.KeplerHandlerInterceptor";

	@Override
	public ClassMatch enhanceClass() {
		return byClassAnnotationMatch(new String[]{HANDLER_ANNOTATION});
	}

	@Override
	public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
		return new ConstructorInterceptPoint[0];
	}

	@Override
	public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {

		return new InstanceMethodsInterceptPoint[]{

				new DeclaredInstanceMethodsInterceptPoint() {

					@Override
					public ElementMatcher<MethodDescription> getMethodsMatcher() {
						return isPublic().and(named("handle"));
					}

					@Override
					public String getMethodsInterceptor() {
						return INTERCEPT_CLASS;
					}

					@Override
					public boolean isOverrideArgs() {
						return false;
					}
				}
		};
	}

}
